/**
 * 验证对象基类
 */
var Validation = Class.create();
Validation.prototype = {
	initialize : function() {
		this.id = '';
		this.name = '';
		this.min = 1;
		this.max = 2147483647;
		this.pattern = null;
		this.msg = '';
		this.error = [];
		this.required = true;
		this.enable = true;
	},
	keypress : function(event) {
		return true;
	},
	exec : function() {
		if (this.enable) {
			this.error.length = 0;
			var value = $F(this.id).strip();
			this.validate(value)
		}
		return this.error.length == 0 ? true : false;
	},
	validate : function(value) {
		return true;
	}
};

/**
 * 英文验证对象<br/>
 * String 不包含除英文字母a-zA-Z以外的任何字符.
 */
var VAlpha = Class.create();
VAlpha.prototype = Object.extend(new Validation(), {
	initialize : function(id, params) {
		this.id = id;
		this.name = '英文验证项';
		this.pattern = /[a-zA-Z]/g;
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	keypress : function(event) {
	},
	validate : function(value) {
		if (this.required && value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!value.empty() && !this.pattern.test(value))
			this.error.push('[#{name}]输入不正确!!');
		if (!(this.min <= value.length && value.length <= this.max))
			this.error.push('[#{name}]允许的字符长度在 #{min}~#{max}之间!!');
	}
});

/**
 * 英文/数字验证对象<br/>
 * String 不包含除英文字母a-zA-Z及数字0-9以外的任何字符.
 */
var VAlphaNumeric = Class.create();
VAlphaNumeric.prototype = Object.extend(new Validation(), {
	initialize : function(id, params) {
		this.id = id;
		this.name = '英文/数字验证项';
		this.pattern = /[a-zA-Z0-9-]/g
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	keypress : function(event) {
		
	},
	validate : function(value) {
		if (this.required && value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!value.empty() && !this.pattern.test(value))
			this.error.push('[#{name}]输入不正确!!');
		if (!(this.min <= value.length && value.length <= this.max))
			this.error.push('[#{name}]允许的字符长度在 #{min}~#{max}之间!!');
	}
});

/**
 * 中文验证对象
 */
var VChinese = Class.create();
VChinese.prototype = Object.extend(new Validation(), {
	initialize : function(id, params) {
		this.id = id;
		this.name = '中文验证项';
		this.pattern =  /^[\u0391-\uFFE5]+$/;
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	validate : function(value) {
		if (this.required && value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!value.empty() && !this.pattern.test(value))
			this.error.push('[#{name}]输入不正确!!');
		if (!(this.min <= value.length && value.length <= this.max))
			this.error.push('[#{name}]允许的数值在 #{min}~#{max}之间!!');
	}
});

/**
 * 比较验证对象
 */
var VCompare = Class.create();
VCompare.prototype = Object.extend(new Validation(), {
	initialize : function(id, compareTo, params) {
		this.id = id;
		this.name = '比较验证项';
		this.compareTo = compareTo;
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	validate : function(value) {
		if (this.required && value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!value.empty() && !(value == $F(this.compareTo).strip()))
			this.error.push('[#{name}]比较出输入不一致!!');
		/*if (!(this.min <= value && value <= this.max))
			this.error.push('[#{name}]允许的数值在 #{min}~#{max}之间!!');*/
	}
});

/**
 * 日期验证对象 yyyy mm dd, yyyy/mm/dd, yyyy.mm.dd, yyyy-mm-dd
 */
var VDate = Class.create();
VDate.prototype = Object.extend(new Validation(), {
	initialize : function(id, params) {
		this.id = id;
		this.name = '日期验证项';
		this.pattern = /^(\d{4})[\s\.\/-](\d{1,2})[\s\.\/-](\d{1,2})$/;
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	validate : function(value) {
		if (this.required && value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!value.empty() && !this.matching(value))
			this.error.push('[#{name}]输入不正确!!');
	},
	matching : function(value) {
		if (this.pattern.test(value)) {
			var result = value.match(this.pattern);
			var y = result[1];
			var m = result[2];
			var d = result[3];

			if (m < 1 || m > 12 || y < 1900 || y > 2100) {
				return false;
			}
			if (m == 2) {
				var days = ((y % 4) == 0) ? 29 : 28;
			} else {
				if (m == 4 || m == 6 || m == 9 || m == 11) {
					var days = 30;
				} else {
					var days = 31;
				}
			}
			return (d >= 1 && d <= days);
		} else {
			return false;
		}
	}
});

/**
 * 电子邮件验证对象
 */
var VEMail = Class.create();
VEMail.prototype = Object.extend(new Validation(), {
	initialize : function(id, params) {
		this.id = id;
		this.name = '电子邮件验证项';
		this.pattern = /^[^\s()<>@,;:\/]+@\w[\w\.-]+\.[a-z]{2,}$/;
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	validate : function(value) {
		if (this.required && value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!value.empty() && !this.pattern.test(value))
			this.error.push('[#{name}]输入不正确!!');
		if (!(this.min <= value.length && value.length <= this.max))
			this.error.push('[#{name}]允许的字符长度在 #{min}~#{max}之间!!');
	}
});

/**
 * 非空验证对象
 */
var VRequired = Class.create();
VRequired.prototype = Object.extend(new Validation(), {
	initialize : function(id, params) {
		this.id = id;
		this.name = '非空验证项';
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	validate : function(value) {
		if (value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!(this.min <= value.length && value.length <= this.max))
			this.error.push('[#{name}]允许的字符长度在 #{min}~#{max} 之间!!');
	}
});


/**
 * 电话号码验证 000-0000000 0000-0000000 000-00000000 0000-00000000
 */
var VPhone = Class.create();
VPhone.prototype = Object.extend(new Validation(),{
	initialize : function(id, params) {
		this.id = id;
		this.name = '电话号码验证项';
		this.pattern = /(^[0-9]{3,4}\-[0-9]{7,8}$)|(^[0-9]{7,8}$)|(^\([0-9]{3,4}\)[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)/;// /^\(?[2-9]\d{2}[\)\.-]?\s?\d{3}[\s\.-]?\d{4}$/
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	validate : function(value) {
		if (this.required && value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!value.empty() && !this.pattern.test(value))
			this.error.push('[#{name}]输入不正确!!');
	}
});


/**
 * 网址验证
 */
var VURL = Class.create();
VURL.prototype = Object.extend(new Validation(), {
	initialize : function(id, params) {
		this.id = id;
		this.name = '网址验证项';
		this.pattern = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	validate : function(value) {
		if (this.required && value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!value.empty() && !this.pattern.test(value))
			this.error.push('[#{name}]输入不正确!!');
	}
});

/**
 * 数值验证对象
 */
var VNumerical = Class.create();
VNumerical.prototype = Object.extend(new Validation(), {
	initialize : function(id, params) {
		this.id = id;
		this.name = '数值验证项';
		this.pattern = /^(([1-9]\d*)|0)(\.\d{1,2})?$/;
		if (params != undefined) {
			for ( var item in params) {
				if (this[item] == undefined || true)
					this[item] = params[item];
			}
		}
	},
	validate : function(value) {
		if (this.required && value.empty())
			this.error.push('[#{name}]不能为空!!');
		if (!value.empty() && !this.pattern.test(value))
			this.error.push('[#{name}]输入不正确!!');
		if (!(this.min <= value && value <= this.max))
			this.error.push('[#{name}]允许的数值在 #{min}~#{max}之间!!');
	}
});

var Validator = Class.create();
Validator.prototype = {
	initialize : function(form) {
		this.validations = {};
		if (form != undefined){
			this.form = $(form);
			this.form.onsubmit = this.submit.bindAsEventListener(this);
			this.form.onreset = this.reset.bindAsEventListener(this);
		}
	},
	add : function(validation) {
		if (validation instanceof Validation) {
			var id = validation.id;
			var element = $(id);
			if (element.type == 'text' || element.type == 'password')
				element.maxLength = validation.max;
			element.onblur = this.handleMessage.bindAsEventListener(this);
			element.onkeypress = validation.keypress.bindAsEventListener(this)
			element.onfocus = this.handleMessage.bindAsEventListener(this);
			if ($(id + '_Tip') == null) {
				new Insertion.After(id, this.setTip(validation));
			}
			this.validations[id] = validation;
		}
		return this;
	},
	remove : function(id) {
		this.validations[id] = null;
	},
	enable : function(ids) {
		var idlist = ids.split(',');
		for (i = 0; i < idlist.length; i++) {
			this.validations[idlist[i]].enable = true;
		}
	},
	disable : function(ids) {
		var idlist = ids.split(',');
		for (i = 0; i < idlist.length; i++) {
			var validation = this.validations[idlist[i]];
            validation.enable = false;
            var element = $(idlist[i] + '_Tip');
            element.className = 'msg';
            element.innerHTML = validation.msg;
		}
	},
	handleMessage : function(event) {
		var id = Event.element(event).id;
		var eventName = event.type;
		var validation = this.validations[id];
		var element = $(id + '_Tip');
		if (eventName == 'focus') {
			element.className = 'msg';
			element.innerHTML = validation.msg;
		} else if (eventName == 'blur') {
            validation.error.length = 0;
			if (!validation.exec()) {
				element.className = 'error';
				element.innerHTML = validation.error[0].interpolate(validation);
			}
		}
	},
	setTip : function(validation) {
		return "<span class='msg' id='" + validation.id + "_Tip'>"
				+ validation.msg + "</span>";
	},
	prepare : function() {
	},
	submit : function() {
		this.prepare();
		var cansubmit = true;
		for (id in this.validations) {
			var validation = this.validations[id];
			var element = $(id);
			if (validation instanceof Validation) {
				if (!validation.exec()) {
					element.focus();
					element.blur();
					cansubmit = false;
				}
			}
		}
		return cansubmit;
	},
	reset : function() {
		for (id in this.validations) {
			var validation = this.validations[id];
			if (validation instanceof Validation) {
				var element = $(id + '_Tip');
				element.className = 'msg';
				element.innerHTML = validation.msg;
			}
		}
	}
};

var EmapValidator = Class.create();
EmapValidator.prototype = Object.extend(new Validator(), {
	setTip : function(validation) {
		return "<div class='msg' id='" + validation.id + "_Tip'>"
				+ validation.msg + "</div>";
	}
});

var BubbleValidator = Class.create();
BubbleValidator.prototype = Object.extend(new Validator(), {
	initialize : function(form) {
		this.validations = {};
		if (form != undefined){
			this.form = $(form);
			this.errors = {};
			this.errorscount = 0;
			this.current = null;
			this.form.onsubmit = this.submit.bindAsEventListener(this);
			this.form.onreset = this.reset.bindAsEventListener(this);
			this.element = this.createElement("div");
			this.element.id = this.form+"_Bubble";
			this.element.style.display="none";
			document.body.appendChild(this.element);
		}
		//window.onload = function(){window.onresize = this.resize();}
		//Event.observe(window,'onresize', this.resize()); 
	},
	add : function(validation) {
		if (validation instanceof Validation) {
			var id = validation.id;
			var element = $(id);
			if (element.type == 'text' || element.type == 'password')
				element.maxLength = validation.max;
			element.onblur = this.handleMessage.bindAsEventListener(this);
			element.onkeypress = validation.keypress.bindAsEventListener(this)
			element.onfocus = this.handleMessage.bindAsEventListener(this);
			this.validations[id] = validation;
		}
		return this;
	},
	handleMessage : function(event) {
		var id = Event.element(event).id;
		var eventName = event.type;
		var validation = this.validations[id];
		this.current = validation;
		var errorsinfo = '',msg='';
		if (this.errors[validation.id]!=undefined){
			delete this.errors[validation.id]
			this.errorscount--;
		}
		if (eventName == 'focus'){
			msg = validation.msg==''?validation.name:validation.msg
		} else if (eventName == 'blur') {
			if (!validation.exec()){
				this.errors[validation.id] =  validation.error[0].interpolate(validation);		
				this.errorscount++;
			} else {
				if (this.errors==''){
					this.hidePopup();
				}
			}
		}
		if(this.errorscount!=0){
			errorsinfo = eventName == 'focus'?"<hr>":errorsinfo;	
			for(e in this.errors){
				errorsinfo += this.errors[e]+"<br/>"
			}
		}	
		this.showPopup(msg,errorsinfo,event);
	},
	submit : function() {
		this.prepare();
		var cansubmit = true;
		for (id in this.validations) {
			var validation = this.validations[id];
			var element = $(id);
			if (validation instanceof Validation) {
				if (!validation.exec()) {
					element.focus();
					element.blur();
					cansubmit = false;
				}
			}
		}
		return cansubmit;
	},
	reset : function() {
		this.hidePopup();
		this.errorscount=0;
		this.errors={};
	},
	showPopup : function(msg,error,event){
		var evt = event ? event : (window.event ? window.event : null);  
		var e = Event.element(event)
		//var x = Event.pointerX(evt)+5;
		var x = e.cumulativeOffset()[0]+e.getWidth()+20;
		//var y = Event.pointerY(evt)+5;
		var y = e.cumulativeOffset()[1]+5;
		this.element.innerHTML='\
			  <table style="top:' + y + 'px; left:' + x + 'px;" class="popup">\
				<tbody>\
				  <tr>\
					<td class="corner" id="topleft"></td>\
					<td class="top"></td>\
					<td class="corner" id="topright"></td>\
				  </tr>\
				  <tr>\
					<td class="left"></td>\
					<td><table class="popup-contents">\
					  <tbody>\
						  <tr>\
							<td class="popup-msg">' +msg + '</td>\
						  </tr>\
						   <tr>\
							<td class="popup-error">' +error + '</td>\
						  </tr>\
					  </tbody>\
					</table></td>\
					<td class="right"></td>\
				  </tr>\
				  <tr>\
					<td id="bottomleft" class="corner"></td>\
					<td class="bottom"><!--<img src="/images/bubble-tail2.png" alt="popup tail" height="29" width="30">--></td>\
					<td class="corner" id="bottomright"></td>\
				  </tr>\
				</tbody>\
			  </table>';
		this.element.style.display='';
	},
	hidePopup : function (){
		this.element.style.display="none";
	},
	createElement : function(e) {
		if (typeof document.createElementNS != 'undefined') {
			return document.createElementNS('http://www.w3.org/1999/xhtml', e);
		}
		if (typeof document.createElement != 'undefined') {
			return document.createElement(e);
		}
		return false;
	}/*,
	resize : function(){
		alert(0)
		if(this.current!=null){
			$(this.current.id).focus();
			$(this.current.id).blur();
		}
	}*/
});